package ego

import (
	"net/http"

	"gitee.com/knowgo/ego/egoc"
	"gitee.com/knowgo/ego/log"

	"gitee.com/knowgo/ego/core"
	"gitee.com/knowgo/ego/http/api"
	"gitee.com/knowgo/ego/http/doc"
)

type Ego struct {
	log         log.Logger
	core        *core.Core
	handler     *api.ApiHandler
	loaders     []egoc.Loader
	coreInited  bool
	coreInitErr error
}

func NewWithLogger(log log.Logger) *Ego {
	var core = core.NewCore(log)
	return &Ego{
		log:     log,
		core:    core,
		handler: api.NewApiHandler(core, log),
	}
}

func New() *Ego {
	var log = log.NewLog()
	var core = core.NewCore(log)
	return &Ego{
		log:     log,
		core:    core,
		handler: api.NewApiHandler(core, log),
	}
}

func (e *Ego) GetHandle() (http.Handler, error) {
	if !e.coreInited {
		for _, loader := range e.loaders {
			if err := e.core.Register(loader); err != nil {
				e.coreInitErr = err
				break
			}
		}
		e.coreInited = true
	}
	return e.handler, e.coreInitErr
}

func (e *Ego) SetRequestTimeFormat(format egoc.TimeFormat) *Ego {
	e.core.SetRequestTimeFormat(format)
	return e
}

func (e *Ego) RegisterProvider(fn interface{}) error {
	return e.core.RegisterInjector(fn)
}

// RegisterDcoApi 注册 api 文档接口
func (e *Ego) RegisterDcoApi() error {
	if err := e.core.RegisterInjector(func(ctx *egoc.Context) (*core.Core, error) {
		return e.core, nil
	}); err != nil {
		return err
	}
	e.core.Register(&doc.EgoApiDoc{})
	return nil
}

func (e *Ego) Register(loader ...egoc.Loader) *Ego {
	e.loaders = append(e.loaders, loader...)
	return e
}

func (e *Ego) AddInterceptor(interceptor func(ctx *egoc.Context) bool) *Ego {
	e.handler.AddInterceptor(interceptor)
	return e
}

func (e *Ego) SetLogRequest(log bool) *Ego {
	e.handler.SetLogRequest(log)
	return e
}

func (e *Ego) ConfigureCors(fn func(ctx *egoc.Context)) *Ego {
	e.handler.ConfigureCors(fn)
	return e
}

func (e *Ego) SetUploadMaxBytes(max int64) *Ego {
	e.handler.SetUploadMaxBytes(max)
	return e
}
